/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Domain;

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import objects.User;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import objects.Frm;
import objects.Message;
import objects.Trd;

/**
 *
 * @author Tal Cohen
 */
public class DataManager {
	public static final int DISCONNECTED = 0;
	public static final int CONNECTED = 1;

	public static int FAILURE = 0;
	public static int SUCCESS = 1;

	private int _userType;       // 0 - defaultUser , 1 - manager
	private String _currUser;
	private String _currForum;
	private String _currThread;

	private Vector<User> _users;
	private Vector<User> _friends;
	private Vector<Frm> _forums;
	private Vector<Trd> _threads;
	private Vector<Message> _messages;
	private int _successOrFailure;
	private Vector<String> _notifications;
	private Vector<String> _errors;
	private boolean _available;
	private boolean _registered;
	private boolean _connected;
	
	private Semaphore _vectorUsersSem;
	private Semaphore _vectorForumsSem;
	private Semaphore _vectorFriendsSem;
	private Semaphore _vectorMessagesSem;
	private Semaphore _successOrFailureSem;
	private Semaphore _vectorThreadsSem;
	private Semaphore _typeOfUserSem;
	private Semaphore _notificationSem;
	private Semaphore _errorSem;
	private Semaphore _availableSem;
	private Semaphore _registeredSem;
	private Semaphore _connectedSem;
	
	private final Object _notificationsLock;
	private final Object _errorLock;


	//    private Controller _controller;

	public DataManager()
	{
		this._userType = 0;
		this._currForum = "";
		this._currThread= "";
		this._currUser="";
		this._users = null;
		this._friends = null;
		this._messages = null;
		this._notifications = new Vector<String>();
		this._errors = new Vector<String>();
		this._forums = new Vector<Frm>(1,0);
		this._available = false;
		this._registered = false;
		this._connected = false;

		this._vectorUsersSem = new Semaphore(0);
		this._vectorForumsSem = new Semaphore(0);
		this._vectorFriendsSem = new Semaphore(0);
		this._vectorMessagesSem = new Semaphore(0);
		this._successOrFailureSem = new Semaphore(0);
		this._vectorThreadsSem = new Semaphore(0);
		this._typeOfUserSem = new Semaphore(0);
		this._notificationSem = new Semaphore(0);
		this._errorSem = new Semaphore(0);
		this._availableSem = new Semaphore(0);
		this._registeredSem = new Semaphore(0);
		this._connectedSem = new Semaphore(0);
		this._notificationsLock = new Object();
		this._errorLock = new Object();
	}

	public synchronized String getCurrForum()
	{
		return _currForum;
	}

	public synchronized String  getCurrThread()
	{
		return _currThread;
	}

	public synchronized void setCurrForum(String _currForum)
	{
		this._currForum = _currForum;
	}

	public synchronized void setCurrThread(String _currThread) {
		this._currThread = _currThread;
	}

	public synchronized void setCurrUser(String user)
	{
		this._currUser = user;
	}

	public synchronized String getCurrUser() {
		return this._currUser;
	}


	//------------------------------------------------getting the User Vector------------------------------------------

	public void setVectorOfUsers(Vector<User> users) {
		this._users = users;
		this._vectorUsersSem.release();
	}

	public Vector<User> getVectorUser()
	{
		try {
			if(!this._vectorUsersSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._users;
	}

	//------------------------------------------------getting the friends Vector------------------------------------------

	public void setVerctorFriends(Vector<User> friends) {
		this._friends = friends;
		this._vectorFriendsSem.release();
	}

	public Vector<User> getVectorFriends()
	{
		try {
			if(!this._vectorFriendsSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._friends;
	}

	//------------------------------------------------getting the forums Vector------------------------------------------

	public void setVectorForums(Vector<Frm> forums) {
		this._forums = forums;
		this._vectorForumsSem.release();
	}

	public Vector<Frm> getVectorForums()
	{
		try {
			if(!this._vectorForumsSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._forums;
	}

	//------------------------------------------------getting the Threads Vector------------------------------------------

	public void setVerctorThreads(Vector<Trd> threads) {
		this._threads = threads;
		this._vectorThreadsSem.release();
	}

	public Vector<Trd> getVectorThreads()
	{
		try {
			if(!this._vectorThreadsSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._threads;
	}
	
	//------------------------------------------------getting the Messages Vector------------------------------------------

	public void setVerctorMesseges(Vector<Message> messages) {
		this._messages = messages;
		this._vectorMessagesSem.release();
	}

	public Vector<Message> getVectorMessages()
	{
		try {
			if(!this._vectorMessagesSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._messages;
	}

	//------------------------------------------------checking success------------------------------------------

	public void setSuccessOrFailure(int typeOfExit) {
		this._successOrFailure = typeOfExit;
		this._successOrFailureSem.release();
	}

	public int getSuccessOrFailure()    {
		try {
			if(!this._successOrFailureSem.tryAcquire(5, TimeUnit.SECONDS))
				return DataManager.FAILURE;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._successOrFailure;
	}

	//------------------------------------------------getting type of user------------------------------------------

	public void setTypeOfUser(int type) {
		this._userType = type;
		this._typeOfUserSem.release();
	}

	public int getTypeOfUser(){
		try {
			if(!this._typeOfUserSem.tryAcquire(5, TimeUnit.SECONDS))
				return -1;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		return this._userType;
	}

	public int getCurrTypeOfUser()
	{
		return this._userType;
	}

	//------------------------------------------------getting the next notification------------------------------------------

	public void addNotification(String notif) {
		synchronized (this._notificationsLock)
		{
			this._notifications.add(notif);
		}
	}
	
	public void emptyNotifications()
	{
		synchronized (this._notificationsLock)
		{
			this._notifications = new Vector<String>();
		}
	}

	public Vector<String> getNotification(){

		Vector<String> ans = null;

		synchronized(this._notificationsLock)
		{
			ans = this._notifications;
		}


		return ans;
	}

	//------------------------------------------------getting the error message------------------------------------------

	public void addError(String err) 
	{
		synchronized (this._notificationsLock)
		{
			this._errors.add(err);
			this._errorSem.release();
		}
	}

	public String getError()
	{

		String ans = null;

		try {
			if(!this._errorSem.tryAcquire(5, TimeUnit.SECONDS))
				return null;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		synchronized(this._errorLock)
		{
			ans = this._errors.remove(0);
		}

		return ans;
	}
	
	//------------------------------------------------getting the availability ans------------------------------------------

	public void setAvailable(boolean ans) {
		this._available = ans;
		this._availableSem.release();
	}
	
	public boolean getAvailable()
	{
		try {
			if(!this._availableSem.tryAcquire(5, TimeUnit.SECONDS))
				return false;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}

		return this._available;
	}

	//------------------------------------------------getting registered------------------------------------------
	
	public void setRegisteredFalse() {
		this._registered = false;
	}	
	
	public void setRegisteredTrue() {
		this._registered = true;
		this._registeredSem.release();
	}
	
	public boolean getRegistered(){
		try {
			if(!this._registeredSem.tryAcquire(5, TimeUnit.SECONDS))
				return false;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		 
		return true;
	}
	
	//------------------------------------------------getting connected------------------------------------------

	
	public void setConnectedFalse() {
		this._connected = false;
	}

	public void setConnectedTrue() {
		this._connected = true;
		this._connectedSem.release();
	}
	
	public boolean getConnected(){
		try {
			if(!this._connectedSem.tryAcquire(5, TimeUnit.SECONDS))
				return false;
		} catch (InterruptedException ex) {
			Logger.getLogger(DataManager.class.getName()).log(Level.SEVERE, null, ex);
		}

		return true;
	}
	
	public int getUserStatus(){
		if(this._connected)
			return CONNECTED;
		else
			return DISCONNECTED;
	}
}
